From a2a05acc6b82416ed2165d33b351c08fe0b8147b Mon Sep 17 00:00:00 2001 From: Georges Basile Stavracas Neto Date: Sun, 2 Apr 2023 19:18:24 -0300 Subject: [PATCH] gsk/vulkan/renderer: Pass appropriate clip region This part of the Vulkan renderer is almost exactly equal to the GL renderer, and the GL renderer already does that since at least 2a38cecd3351. Copy that into the Vulkan renderer. A nice side effect from this commit is that resizing a window now actually works again. Sneak in a trivial cleanup by using a variable to hold the draw index. --- gsk/vulkan/gskvulkanrenderer.c | 59 ++++++++++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/gsk/vulkan/gskvulkanrenderer.c b/gsk/vulkan/gskvulkanrenderer.c index 8f4fa13bf5..b634a2b761 100644 --- a/gsk/vulkan/gskvulkanrenderer.c +++ b/gsk/vulkan/gskvulkanrenderer.c @@ -70,6 +70,55 @@ struct _GskVulkanRendererClass G_DEFINE_TYPE (GskVulkanRenderer, gsk_vulkan_renderer, GSK_TYPE_RENDERER) +static cairo_region_t * +get_render_region (GskVulkanRenderer *self) +{ + const cairo_region_t *damage; + cairo_region_t *render_region; + cairo_region_t *scaled_damage; + GdkRectangle whole_surface; + GdkRectangle extents; + GdkSurface *surface; + int scale; + + render_region = NULL; + surface = gdk_draw_context_get_surface (GDK_DRAW_CONTEXT (self->vulkan)); + scale = gdk_surface_get_scale_factor (surface); + + whole_surface.x = 0; + whole_surface.y = 0; + whole_surface.width = gdk_surface_get_width (surface); + whole_surface.height = gdk_surface_get_height (surface); + + damage = gdk_draw_context_get_frame_region (GDK_DRAW_CONTEXT (self->vulkan)); + scaled_damage = cairo_region_create (); + for (int i = 0; i < cairo_region_num_rectangles (damage); i++) + { + cairo_rectangle_int_t rect; + cairo_region_get_rectangle (damage, i, &rect); + cairo_region_union_rectangle (scaled_damage, &(cairo_rectangle_int_t) { + .x = rect.x * scale, + .y = rect.y * scale, + .width = rect.width * scale, + .height = rect.height * scale, + }); + } + + if (cairo_region_contains_rectangle (scaled_damage, &whole_surface) == CAIRO_REGION_OVERLAP_IN) + goto out; + + cairo_region_get_extents (scaled_damage, &extents); + if (gdk_rectangle_equal (&extents, &whole_surface)) + goto out; + + render_region = cairo_region_create_rectangle (&extents); + +out: + g_clear_pointer (&scaled_damage, cairo_region_destroy); + + return g_steal_pointer (&render_region); +} + static void gsk_vulkan_renderer_free_targets (GskVulkanRenderer *self) { @@ -239,11 +288,12 @@ gsk_vulkan_renderer_render (GskRenderer *renderer, { GskVulkanRenderer *self = GSK_VULKAN_RENDERER (renderer); GskVulkanRender *render; - const cairo_region_t *clip; + cairo_region_t *render_region; #ifdef G_ENABLE_DEBUG GskProfiler *profiler; gint64 cpu_time; #endif + uint32_t draw_index; #ifdef G_ENABLE_DEBUG profiler = gsk_renderer_get_profiler (renderer); @@ -256,8 +306,9 @@ gsk_vulkan_renderer_render (GskRenderer *renderer, gdk_draw_context_begin_frame (GDK_DRAW_CONTEXT (self->vulkan), region); render = self->render; - clip = gdk_draw_context_get_frame_region (GDK_DRAW_CONTEXT (self->vulkan)); - gsk_vulkan_render_reset (render, self->targets[gdk_vulkan_context_get_draw_index (self->vulkan)], NULL, clip); + render_region = get_render_region (self); + draw_index = gdk_vulkan_context_get_draw_index (self->vulkan); + gsk_vulkan_render_reset (render, self->targets[draw_index], NULL, render_region); gsk_vulkan_render_add_node (render, root); @@ -275,6 +326,8 @@ gsk_vulkan_renderer_render (GskRenderer *renderer, #endif gdk_draw_context_end_frame (GDK_DRAW_CONTEXT (self->vulkan)); + + g_clear_pointer (&render_region, cairo_region_destroy); } static void -- 2.30.2